/**
 * @Author: wzplove
 * @Author: <EMAIL>
 * @Date: 2021/12/28 14:05
 * @Desc: 处理常见的 Http 错误响应代码
 */
package helper

import (
	"errors"
	"fmt"
	"net/http"
	"strings"
)

var (
	ErrRecordNotFound = errors.New("record not found")
	ErrEditConflict   = errors.New("edit conflict")
	ErrDuplicateEmail   = errors.New("duplicate email")
)

/**
 * @Desc: log错误处理
 */
func (h *Helper) LogError(r *http.Request, err error) {
    h.Logger.Error(err, map[string]string{
		"requestMethod": r.Method,
		"requestUrl":    r.URL.String(),
	})
}

/**
 * @Desc: error错误处理
 */
func (h *Helper) ErrorResponse(w http.ResponseWriter, r *http.Request, status int, message string) {
	data := map[string]interface{}{"message": message}
	resp := h.NewResponse(-1, data)
	err  := h.WriteJSON(w, status, resp, nil)

	if err != nil {
		h.LogError(r, err)
		w.WriteHeader(http.StatusInternalServerError)
	}
}

/**
 * @Desc: Forbidden错误处理
 */
func (h *Helper) ForbiddenResponse(w http.ResponseWriter, r *http.Request) {
	message := "you do not have permission to access this resource"
	h.ErrorResponse(w, r, http.StatusForbidden, message)
}

/**
 * @Desc: ServerError错误处理
 */
func (h *Helper) ServerErrorResponse(w http.ResponseWriter, r *http.Request, err error) {
	h.LogError(r, err)
	message := "the server encountered a problem and could not process your request"
	h.ErrorResponse(w, r, http.StatusInternalServerError, message)
}

/**
 * @Desc: NotFound错误处理
 */
 func (h *Helper) NotFoundResponse(w http.ResponseWriter, r *http.Request) {
	message := "the requested resource could not be found"
	h.ErrorResponse(w, r, http.StatusNotFound, message)
}

/**
 * @Desc: MethodNotAllowed错误处理
 */
func (h *Helper) MethodNotAllowedResponse(w http.ResponseWriter, r *http.Request) {
	message := "the request method is not allowed"
	h.ErrorResponse(w, r, http.StatusMethodNotAllowed, message)
}

/**
 * @Desc: BadRequest错误处理
 */
func (h *Helper) BadRequestResponse(w http.ResponseWriter, r *http.Request, err error) {
	h.ErrorResponse(w, r, http.StatusBadRequest, err.Error())
}

/**
 * @Desc: FailedValidation错误处理
 */
func (h *Helper) FailedValidationResponse(w http.ResponseWriter, r *http.Request, errors map[string]string) {
	var strBuilder strings.Builder
	for key, value := range errors {
		strBuilder.WriteString(fmt.Sprintf("%s: %s,", key, value))
	}

	result := strBuilder.String()
	if len(result) > 0 {
		result = result[:len(result)-2]
		result += "."
	}
	h.ErrorResponse(w, r, http.StatusUnprocessableEntity, result)
}

/**
 * @Desc: EditConflict错误处理
 */
func (h *Helper) EditConflictResponse(w http.ResponseWriter, r *http.Request) {
	message := "unable to update the record due to an edit conflict (try again later)"
	h.ErrorResponse(w, r, http.StatusConflict, message)
}

/**
 * @Desc: RateLimitExceeded错误处理
 */
func (h *Helper) RateLimitExceededResponse(w http.ResponseWriter, r *http.Request) {
	message := "rate limit exceeded"
	h.ErrorResponse(w, r, http.StatusTooManyRequests, message)
}

/**
 * @Desc: InvalidCredentials错误处理
 */
func (h *Helper) InvalidCredentialsResponse(w http.ResponseWriter, r *http.Request) {
	message := "invalid authentication credentials"
	h.ErrorResponse(w, r, http.StatusUnauthorized, message)
}

/**
 * @Desc: InvalidAuthenticationToken错误处理
 */
func (h *Helper) InvalidAuthenticationTokenResponse(w http.ResponseWriter, r *http.Request) {
	message := "invalid or expired authentication token"
	h.ErrorResponse(w, r, http.StatusUnauthorized, message)
}

/**
 * @Desc: AuthenticationRequired错误处理
 */
func (h *Helper) AuthenticationRequiredResponse(w http.ResponseWriter, r *http.Request) {
	message := "authentication required to access this resource"
	h.ErrorResponse(w, r, http.StatusUnauthorized, message)
}

/**
 * @Desc: NotPermitted错误处理
 */
func (h *Helper) NotPermittedResponse(w http.ResponseWriter, r *http.Request) {
	message := "you do not have permission to perform this action"
	h.ErrorResponse(w, r, http.StatusForbidden, message)
}